/*	
	update file operation:
		updatefile P1 P2 
				P1 – file path
 				P2 – data file path (from local hard disk)
	updatefile (file_path, data) – Update/Edit the contents of a file specified 
	by <file_path> with <data>.	

*/

#include <stdio.h>
#include <string.h>
#include "..//include//createvfs.h"
#include "..//include//n_ary.h"
#include "..//include//vfs_errorcodes.h"

int updatefileop(char filepath[], char datafilepath[], char filename_g[]) {

	struct Block b;
	struct header headervar;
	struct FD file_desc;

	FILE *fp, *f_data;

	char newstr2[100], abspath[100], fdpath[100];
	char data[1024] = "", ch, d[2];
	int num, j = 0, level = 0, count = 1, pos = 1, i, k = 0;
	int bnum,z=0, flag_size = 0;
	
	// VFS insufficient arguments
	if ((strcmp(filepath,"") == 0) || (strcmp(datafilepath,"")== 0)) {
		printf("updatefile_FAILURE %s\n", ERR_VFS_UPDATEFILE_00);
		return 0;
	}
		
	/*
		Traversing n-ary tree to search a file/ folder based on pathname
		and returning the corresponding node to the user.
	*/
	
    Tree cur_tree;   
    Tree prev_tree;
    Tree sib = cur_tree;
    Tree new;
    NODE first = NULL;   
    NODE cur = first;
    NODE last;

    // Split the path based on '/'
    while(filepath[pos]!='\0'){
		strcat(abspath,"/");	
        j=0;
   	    num=splitupdt(filepath,pos);
         
       	if(num>(strlen(filepath)-1)) 
       		num = strlen(filepath)-1;
         
        for(i=pos; i<=num; i++){
    	    newstr2[j]=filepath[i];
    	    j++;
    	}
        newstr2[j]='\0';     
               
	    first=insert_rear_ll(newstr2,abspath,first);
	    strcat(abspath,newstr2);
        if(num>=strlen(filepath)-1) 
        	break;
        pos=num+2;
	}

   	last=cur;
   	cur=first;
   	while(cur->next!=NULL) {
       	count=count+1;
       	cur=cur->next;
   	}   
	

   	cur=first;
   	cur_tree=root->left;
   	sib=root->left;
   	prev_tree=root;     
   	while(count > 0){														// count = 1 => leaf node
		if(cur_tree!=NULL){ 
		   	if(strcmp(cur_tree->node_label,cur->entry) == 0 && count!=1){  // if (the two strings are equal) {...}
           		cur=cur->next;
       			prev_tree=cur_tree;
				cur_tree=cur_tree->left;
				sib=cur_tree;
				count=count-1;
    		}
       		else if(strcmp(cur_tree->node_label,cur->entry) == 0 && count==1){
       			count = count-1;
       		}
       		else {	// traverse to the right siblings
       			prev_tree = cur_tree;
       			cur_tree = cur_tree -> right;
       		}
       	}
       	else {
      		printf("updatefile_FAILURE %s\n",ERR_VFS_UPDATEFILE_01);
			return 0;
       	}
    }
     
	// cur_tree is the node to be updated
	strcpy(fdpath,"");
    strcat(fdpath,cur_tree->path);
    strcat(fdpath,cur_tree->node_label);

	fp = fopen(filename_g, "rb+");
	if(fp==NULL) {
		printf("updatefile_FAILURE %s\n",ERR_VFS_UPDATEFILE_01);
 		return 0;
 	}
	
	rewind(fp);
	fread(&headervar, sizeof(struct header), 1, fp);

	// seek to the start of FD block
	rewind(fp);
	fseek(fp, LABEL_SIZE*sizeof(char) + 2*(sizeof(int)), SEEK_SET); 
			
	i=0;
	while(i < headervar.total_desc) {
		fread(&file_desc, sizeof(struct FD), 1, fp);
		if (strcmp(file_desc.path,fdpath) == 0) {
			bnum = file_desc.blockno;
			break;
		}
		i++;
	}
		 		
 	rewind(fp);
  	fseek(fp, sizeof(struct header)+sizeof(int)*num_blocks, SEEK_SET);
	// fseek to the starting position of the first block of the block list
	  		

	fseek(fp, 1024 * (bnum-1), SEEK_CUR);
	// fseek to the desired block number
						
		
	f_data = fopen(datafilepath,"rt");
	if (f_data == NULL) {
		printf("updatefile_FAILURE %s\n", ERR_VFS_UPDATEFILE_02);
    	return 0;
	}
	z = 0;
	while(!feof(f_data)) {
		ch = fgetc(f_data);
		d[0]=ch;
        d[1]='\0';
        if(ch != EOF){
            strcat(data,d);
            z = z + 1;
        }
        if(z>=1024) {
        	flag_size = 1;
        	break;
        }
	}
    strcat(data,"\0");
	if(flag_size == 1){
		fclose(f_data);       
		printf("updatefile_FAILURE %s\n", ERR_VFS_UPDATEFILE_03);
    	return 0;
	}
	data[z]='\0';
	fclose(f_data);
		 
	strcpy(b.blk, data);       
	fwrite(&b, sizeof(struct Block), 1, fp);
	fclose(fp);
	return 1;	
}

int splitupdt(char *str,int pos){
   int j,i;
   j=0;
   for(i=pos; i<strlen(str);i++){
      if(str[i]=='/' || str[i]=='"') return i-1;
   }
   return i;
}
